package com.dhz.wlzs.app.service.impl;

import java.util.ArrayList;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

@Component
public class RestTemplateService {
	private static final Logger logger = LoggerFactory.getLogger(RestTemplateService.class.getName());
	@Autowired
	private RestTemplate restTemplate;

	@Bean
	public RestTemplate restTemplate() {
		restTemplate = new RestTemplate(new ArrayList<HttpMessageConverter<?>>() {
			private static final long serialVersionUID = 102455248343724262L;
			{
				add(new FastJsonHttpMessageConverter());
				// add(new ByteArrayHttpMessageConverter());
				// add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
				// add(new ResourceHttpMessageConverter());
				// add(new SourceHttpMessageConverter<>());
				// add(new FormHttpMessageConverter());
				// add(new MappingJackson2HttpMessageConverter());
			}
		});
		restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
		return restTemplate;
	}

	public String doGet(String url) {
		return restTemplate.getForObject(url, String.class);
	}

	public String doPost(String url) {
		return restTemplate.postForObject(url, HttpEntity.EMPTY, String.class);
	}

	/**
	 * post请求
	 * 
	 * @param uri
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public String doPost(String uri, Map<String, Object> params) throws Exception {
		return doPost(uri, params, null, String.class);
	}

	public <T> T doPost(String uri, Map<String, Object> params, HttpHeaders headers, Class<T> result) throws Exception {
		return doPost(uri, params, headers, result, 5000);
	}

	public <T> T doPost(String uri, Map<String, Object> params, HttpHeaders headers, Class<T> result, int readTimeout)
			throws Exception {
		return doPost(uri, params, headers, result, readTimeout, readTimeout);
	}

	public <T> T doPost(String uri, Map<String, Object> params, HttpHeaders headers, Class<T> result, int readTimeout,
			int connectTimeout) throws Exception {
		RestTemplate template = restTemplate;
		SimpleClientHttpRequestFactory factory = ((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory());
		factory.setConnectTimeout(connectTimeout);
		factory.setReadTimeout(readTimeout);
		template.setRequestFactory(factory);
		trustAllHttpsCertificates();
		HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
			public boolean verify(String urlHostName, SSLSession session) {
				logger.debug("trust  URL Host: " + urlHostName + " vs. " + session.getPeerHost());
				return true;
			}
		});
		if (null == headers) {
			headers = getDefaultHeaders();
		}
		HttpEntity<Map<String, Object>> entity = new HttpEntity<Map<String, Object>>(params, headers);
		ResponseEntity<T> response = template.exchange(uri, HttpMethod.POST, entity, result);
		return response.getBody();
	}

	/**
	 * 返回一个请求头
	 * 
	 * @param mediaType
	 *            请求类型例如MediaType.APPLICATION_JSON
	 * @param headerMap
	 *            请求头信息
	 * @return
	 */
	public HttpHeaders getHeaders(MediaType mediaType, Map<String, String> headerMap) {
		HttpHeaders httpHeaders = new HttpHeaders();
		// 设置请求的类型
		httpHeaders.setContentType(mediaType);
		// 请求头信息
		for (Map.Entry<String, String> entry : headerMap.entrySet()) {
			httpHeaders.add(entry.getKey(), entry.getValue());
		}
		return httpHeaders;
	}

	/**
	 * 
	 * @param mediaType
	 *            请求类型例如MediaType.APPLICATION_JSON
	 * @param headerMap
	 *            请求头信息
	 * @param body
	 *            请求的参数
	 * @return
	 */
	public HttpEntity<String> getHttpEntity(MediaType mediaType, Map<String, String> headerMap, String body) {
		return new HttpEntity<String>(body, getHeaders(mediaType, headerMap));
	}

	/**
	 * 请求的参数封装
	 * 
	 * @param httpHeaders
	 *            请求头信息
	 * @param body
	 *            请求参数
	 * @return
	 */
	public HttpEntity<String> getHttpEntity(HttpHeaders httpHeaders, String body) {
		return new HttpEntity<String>(body, httpHeaders);
	}

	public HttpHeaders getJsonHeaders() {
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON);
		headers.set("Accept-Charset", "UTF-8");
		headers.set("contentType", "application/json");
		return headers;
	}

	public HttpHeaders getDefaultHeaders() {
		HttpHeaders headers = new HttpHeaders();
		headers.set("Connection", "Keep-Alive");
		headers.set("Accept-Charset", "UTF-8");
		headers.set("User-Agent",
				"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36");
		return headers;
	}

	private void trustAllHttpsCertificates() throws Exception {
		javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
		javax.net.ssl.TrustManager tm = new MyTrustManager();
		trustAllCerts[0] = tm;
		javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
		sc.init(null, trustAllCerts, null);
		javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
	}

	class MyTrustManager implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
		public java.security.cert.X509Certificate[] getAcceptedIssuers() {
			return null;
		}

		public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
			return true;
		}

		public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
			return true;
		}

		public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
				throws java.security.cert.CertificateException {
			return;
		}

		public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
				throws java.security.cert.CertificateException {
			return;
		}

	}

}
